package com.itheima.web.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class BaseServlet extends HttpServlet {

    protected ApplicationContext ac;
    @Override
    public void init() throws ServletException {
        super.init();
        ac= (ApplicationContext) getServletContext().getAttribute("ac");
    }

    /**
     * service是Servlet的生命周期方法，每次访问Servlet都会执行。
     * 问题：System.out.println(this);打印的是com.itheima.web.controller.CompanyServlet@47b24e46，为什么？
     * 解决：方法中的this表示，哪个对象调用该方法，this就表示哪个对象。当我们客户端发起请求访问CompanyServlet时，tomcat
     * 服务器会创建CompanyServlet对象，创建完成之后会调用init方法初始化，接着调用service方法，也就是
     * companyServlet.service(request,response)，此时我们的companyServlet没有重写这个方法，那么就会使用父类BaseServlet
     * 中定义的service方法，所有此时父类BaseServlet的service方法中打印的this表示的是子类对象。
     */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1 获取标记
        String pathInfo = request.getPathInfo().substring(1);// /findByPage
        //需求：调用子类和标记相同的方法，使用反射技术
        //System.out.println(this); //表示子类对象CompanyServlet
        //2 获取子类中和标记相同的方法对象Method
        try {
            Method method = this.getClass().getDeclaredMethod(pathInfo, HttpServletRequest.class, HttpServletResponse.class);
            //开启访问权限，也叫暴力访问
            method.setAccessible(true);
            //3 反射执行Method对应的方法
            Object result = method.invoke(this, request, response);//相当于companyServlet.findByPage(request,response)
            //将result对象响应给客户端
            writeValue(response,result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
    定义响应json的方法，统一对客户端进行响应
     */
    private void writeValue(HttpServletResponse response,Object obj) throws IOException {
        ObjectMapper objectMapper=new ObjectMapper();
        objectMapper.writeValue(response.getOutputStream(),obj);
    }
}
